.\" Copyright 2016, Eugene Syromyatnikov <evgsyr@gmail.com>
.\" Copyright 2024, Alejandro Colomar <alx@kernel.org>
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
.TH PR_SET_FP_MODE 2const 2024-06-02 "Linux man-pages 6.9.1"
.SH NAME
PR_SET_FP_MODE
\-
set the floating point mode of the calling process
.SH LIBRARY
Standard C library
.RI ( libc ", " \-lc )
.SH SYNOPSIS
.nf
.BR "#include <linux/prctl.h>" "  /* Definition of " PR_* " constants */"
.B #include <sys/prctl.h>
.P
.BI "int prctl(PR_SET_FP_MODE, unsigned long " mode );
.fi
.SH DESCRIPTION
On the MIPS architecture,
user-space code can be built using an ABI which permits
linking with code that has more restrictive floating-point (FP) requirements.
For example,
user-space code may be built to target the O32 FPXX ABI
and linked with code built for either one of the more restrictive
FP32 or FP64 ABIs.
When more restrictive code is linked in,
the overall requirement for the process is to use the more
restrictive floating-point mode.
.P
Because the kernel has no means of knowing in advance
which mode the process should be executed in,
and because these restrictions can
change over the lifetime of the process, the
.B PR_SET_FP_MODE
operation is provided to allow control of the floating-point mode
from user space.
.P
.\" https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
The
.I mode
argument is a bit mask describing the floating-point mode used:
.TP
.B PR_FP_MODE_FR
When this bit is
.I unset
(so called
.BR FR=0 " or " FR0
mode), the 32 floating-point registers are 32 bits wide,
and 64-bit registers are represented as a pair of registers
(even- and odd- numbered,
with the even-numbered register containing the lower 32 bits,
and the odd-numbered register containing the higher 32 bits).
.IP
When this bit is
.I set
(on supported hardware),
the 32 floating-point registers are 64 bits wide (so called
.BR FR=1 " or " FR1
mode).
Note that modern MIPS implementations (MIPS R6 and newer) support
.B FR=1
mode only.
.IP
Applications that use the O32 FP32 ABI can operate only when this bit is
.I unset
.RB ( FR=0 ;
or they can be used with FRE enabled, see below).
Applications that use the O32 FP64 ABI
(and the O32 FP64A ABI, which exists to
provide the ability to operate with existing FP32 code; see below)
can operate only when this bit is
.I set
.RB ( FR=1 ).
Applications that use the O32 FPXX ABI can operate with either
.B FR=0
or
.BR FR=1 .
.TP
.B PR_FP_MODE_FRE
Enable emulation of 32-bit floating-point mode.
When this mode is enabled,
it emulates 32-bit floating-point operations
by raising a reserved-instruction exception
on every instruction that uses 32-bit formats and
the kernel then handles the instruction in software.
(The problem lies in the discrepancy of handling odd-numbered registers
which are the high 32 bits of 64-bit registers with even numbers in
.B FR=0
mode and the lower 32-bit parts of odd-numbered 64-bit registers in
.B FR=1
mode.)
Enabling this bit is necessary when code with the O32 FP32 ABI should operate
with code with compatible the O32 FPXX or O32 FP64A ABIs (which require
.B FR=1
FPU mode) or when it is executed on newer hardware (MIPS R6 onwards)
which lacks
.B FR=0
mode support when a binary with the FP32 ABI is used.
.IP
Note that this mode makes sense only when the FPU is in 64-bit mode
.RB ( FR=1 ).
.IP
Note that the use of emulation inherently has a significant performance hit
and should be avoided if possible.
.P
In the N32/N64 ABI, 64-bit floating-point mode is always used,
so FPU emulation is not required and the FPU always operates in
.B FR=1
mode.
.P
This operation is mainly intended for use by the dynamic linker
.RB ( ld.so (8)).
.SH RETURN VALUE
On success,
0 is returned.
On error, \-1 is returned, and
.I errno
is set to indicate the error.
.SH ERRORS
.TP
.B EOPNOTSUPP
.I mode
has an invalid or unsupported value.
.SH STANDARDS
Linux.
MIPS only.
.SH HISTORY
Linux 4.0 (MIPS).
.\" commit 9791554b45a2acc28247f66a5fd5bbc212a6b8c8
.SH SEE ALSO
.BR prctl (2),
.BR PR_GET_FP_MODE (2const)
